<script setup lang="ts">
import MenuItem from './MenuItem.vue'
import {onMounted, provide, ref, watch} from "vue";
import {useRoute} from 'vue-router'
import type SysPermission from "@/type/entity/sys-permission.ts";

const route = useRoute()

const props = defineProps<{
  menus: SysPermission[]
}>()

//侧边栏菜单组件是否加载完毕
const isReady = ref(false)
const selectedKey = ref('')
const openKeys = ref<Set<string>>(new Set([]))

const handleSelect = (currentKey: string) => {
  selectedKey.value = currentKey
}

function findAncestorKeys(menu: SysPermission[], targetKey: string): string[] | null {
  for (const item of menu) {
    // 如果找到目标key，直接返回当前key
    if (item.permissionCode === targetKey) {
      return [item.permissionCode]
    }
    // 如果有子菜单，递归查找
    if (item.children) {
      const childPath = findAncestorKeys(item.children, targetKey)
      if (childPath) {
        // 找到后，把当前key加在前面
        return [item.permissionCode, ...childPath]
      }
    }
  }
  // 没有找到
  return null
}

onMounted(() => {
  //默认展开
  const initOpenKey = route.path
  const ancestors = findAncestorKeys(props.menus, initOpenKey)
  if (ancestors) {
    // 不要直接 openKeys.value = new Set(ancestors)，这样会把叶子节点也加进去
    // 通常只展开到倒数第一个父级，不包含叶子节点自己
    ancestors.slice(0, -1).forEach(k => openKeys.value.add(k))
    selectedKey.value = initOpenKey
  }
  isReady.value = true
})

//路由变化后联动菜单
watch(() => route.path, (newPath) => {
  const ancestors = findAncestorKeys(props.menus, newPath)
  if (ancestors) {
    ancestors.slice(0, -1).forEach(k => openKeys.value.add(k)) // 展开父级菜单
    selectedKey.value = newPath                      // 设置选中菜单项
  }
}, {immediate: true})  // 初始化也执行一次

provide('openKeys', openKeys)
provide('selectedKey', selectedKey)
provide('handleSelect', handleSelect)
</script>

<template>
  <aside class="sidebar">
    <template v-if="isReady">
      <MenuItem
          v-for="(item) in menus"
          :key="item.id"
          :item="item"
          :level="0"
          @select="(event:SysPermission) => $emit('select', event)"
      />
    </template>
  </aside>
</template>

<style scoped>
.sidebar {
  width: 200px;
  color: #fff;
  height: 100vh;
  padding: 10px;
  overflow-y: auto;
}
</style>